/*
 * rentals_test.c
 *
 *  Created on: May 6, 2011
 *      Author: Gilad & Yotam
 */

#include "test_utilities.h"
#include "../rentals.h"
#include <stdlib.h>
#include <stdbool.h>

#define ASSERT_SUCCESS(b) ASSERT_TEST((RENTALS_SUCCESS) == (b));
#define ASSERT_NULL(b) ASSERT_TEST((RENTALS_NULL_ARGUMENT) == (b));

bool test_rentalsCreateNew() {
	Rentals newRentals = rentalsCreateNew();
	ASSERT_SUCCESS(rentalsAddNewCar(newRentals, 123, "Toyotam", 10, 5));
	ASSERT_SUCCESS(rentalsAddNewCustomer(newRentals, 333, "Gilad"));
	ASSERT_TEST(RENTALS_INVALID_CUSTOMER_ID ==
			rentalsCustomerPayBill(newRentals, 333));
	ASSERT_SUCCESS(rentalsRemoveCar(newRentals, 123));

	ASSERT_SUCCESS(rentalsDestroy(newRentals));
	return true;
}

bool test_rentalsDestroy() {
	/* tested via valgrind*/
	return true;
}

bool test_retnalsAddNewCar() {
	Rentals newRentals = rentalsCreateNew();
	ASSERT_NULL(rentalsAddNewCar(NULL, 60, "nothin", 0, -9));
	ASSERT_TEST(RENTALS_INVALID_PRICE == rentalsAddNewCar(newRentals, 60,
					"nothin", 0, -9));
	ASSERT_TEST(RENTALS_INVALID_KM == rentalsAddNewCar(newRentals, 60, "nothin",
					1, -9));
	ASSERT_SUCCESS(rentalsAddNewCar(newRentals, 999, "Mazda", 9, 200));
	ASSERT_TEST(RENTALS_CAR_ALREADY_EXISTS == rentalsAddNewCar(newRentals, 999,
					"Honda", 9, 22));

	rentalsDestroy(newRentals);
	return true;
}

bool test_rentalsRemoveCar() {
	Rentals newRentals = rentalsCreateNew();
	rentalsAddNewCustomer(newRentals, 2020, "Yosi");
	ASSERT_SUCCESS(rentalsAddNewCar(newRentals, 1111, "stam", 90, 20));
	ASSERT_NULL(rentalsRemoveCar(NULL, 1111));
	ASSERT_TEST(RENTALS_CAR_DOES_NOT_EXISTS == rentalsRemoveCar(newRentals, 2));
	ASSERT_SUCCESS(rentalsRemoveCar(newRentals, 1111));
	ASSERT_TEST(RENTALS_CAR_DOES_NOT_EXISTS == rentalsRemoveCar(newRentals,
					1111));
	ASSERT_SUCCESS(rentalsAddNewCar(newRentals, 1111, "other", 50, 0));
	rentalsCustomerRentCar(newRentals, 2020, 1111);
	ASSERT_TEST(RENTALS_CAR_IN_USE == rentalsRemoveCar(newRentals, 1111));

	rentalsDestroy(newRentals);
	return true;
}

bool test_rentalsPutOnSale() {
	Rentals newRentals = rentalsCreateNew();
	ASSERT_NULL(rentalsPutOnSale(NULL, 11, 40, 30, 20));
	ASSERT_TEST(RENTALS_INVALID_KM == rentalsPutOnSale(newRentals, 11, 40, 30,
					20));
	ASSERT_TEST(RENTALS_INVALID_PRICE == rentalsPutOnSale(newRentals, 11, 20,
					30, 0));
	ASSERT_TEST(RENTALS_CAR_DOES_NOT_EXISTS == rentalsPutOnSale(newRentals, 11,
					20, 30, 20));
	rentalsAddNewCar(newRentals, 11, "blabla", 40, 0);
	ASSERT_TEST(RENTALS_SALE_PRICE_TOO_BIG == rentalsPutOnSale(newRentals, 11,
					10, 20 , 400));
	ASSERT_SUCCESS(rentalsPutOnSale(newRentals, 11, 10, 20, 399));
	ASSERT_TEST(RENTALS_CAR_ALREADY_ON_SALE == rentalsPutOnSale(newRentals, 11,
					40, 50, 1000));

	rentalsDestroy(newRentals);
	return true;
}

bool test_rentalsEndSale() {
	Rentals newRentals = rentalsCreateNew();
	ASSERT_NULL(rentalsEndSale(NULL, 121));
	ASSERT_TEST(RENTALS_CAR_DOES_NOT_EXISTS == rentalsEndSale(newRentals, 121));
	rentalsAddNewCar(newRentals, 121, "Swift", 30, 5);
	rentalsAddNewCustomer(newRentals, 9898, "Shmulik");
	rentalsCustomerRentCar(newRentals, 9898, 121);
	ASSERT_TEST(RENTALS_CAR_IN_USE == rentalsEndSale(newRentals, 121));
	rentalsCustomerReturnCar(newRentals, 9898, 121, 20);
	ASSERT_TEST(RENTALS_CAR_NO_SALE == rentalsEndSale(newRentals, 121));
	rentalsPutOnSale(newRentals, 121, 20, 30, 500);
	ASSERT_SUCCESS(rentalsEndSale(newRentals, 121));

	rentalsDestroy(newRentals);
	return true;
}

bool test_rentalsAddNewCustomer() {
	Rentals newRentals = rentalsCreateNew();
	ASSERT_NULL(rentalsAddNewCustomer(NULL, 5858, "Yuval"));
	ASSERT_SUCCESS(rentalsAddNewCustomer(newRentals, 5858, "Yuval"));
	ASSERT_TEST(RENTALS_CUSTOMER_ALREADY_EXISTS== rentalsAddNewCustomer(
					newRentals, 5858, "Yuval"));

	rentalsDestroy(newRentals);
	return true;
}

bool test_rentalsCustomerRentCar() {
	Rentals newRentals = rentalsCreateNew();
	ASSERT_NULL(rentalsCustomerRentCar(NULL, 222, 90));
	ASSERT_TEST(RENTALS_CAR_DOES_NOT_EXISTS == rentalsCustomerRentCar(
					newRentals, 222, 90 ));
	rentalsAddNewCar(newRentals, 90, "Tata", 30, 200);
	ASSERT_TEST(RENTALS_INVALID_CUSTOMER_ID == rentalsCustomerRentCar(
					newRentals, 222, 90));
	rentalsAddNewCustomer(newRentals, 222, "Shula");
	ASSERT_SUCCESS(rentalsCustomerRentCar(newRentals, 222, 90));

	rentalsDestroy(newRentals);
	return true;
}

bool test_rentalsCustomerReturnCar() {
	Rentals newRentals = rentalsCreateNew();
	ASSERT_NULL(rentalsCustomerReturnCar(NULL, 321, 6060, 0));
	ASSERT_TEST(RENTALS_INVALID_CUSTOMER_ID == rentalsCustomerReturnCar(
					newRentals, 321, 6060, 0));
	rentalsAddNewCustomer(newRentals, 321, "mishu");
	ASSERT_TEST(RENTALS_INVALID_KM == rentalsCustomerReturnCar(newRentals, 321,
					6060, 0));
	rentalsAddNewCar(newRentals, 6060, "Dodge", 40, 0);
	ASSERT_TEST(RENTALS_INVALID_CAR == rentalsCustomerReturnCar(newRentals,
					321, 6060, 3));
	rentalsCustomerRentCar(newRentals, 321, 6060);
	ASSERT_SUCCESS(rentalsCustomerReturnCar(newRentals, 321, 6060, 20));

	rentalsDestroy(newRentals);
	return true;
}

bool test_rentalsCustomerPayBill() {
	Rentals newRentals = rentalsCreateNew();
	ASSERT_NULL(rentalsCustomerPayBill(NULL, 999));
	ASSERT_TEST(RENTALS_INVALID_CUSTOMER_ID == rentalsCustomerPayBill(
					newRentals, 999));
	rentalsAddNewCustomer(newRentals, 999, "keepi");
	ASSERT_TEST(RENTALS_INVALID_CUSTOMER_ID == rentalsCustomerPayBill(
					newRentals, 999));
	rentalsAddNewCar(newRentals, 1111, "lada", 9, 800);
	rentalsCustomerRentCar(newRentals, 999, 1111);
	rentalsCustomerReturnCar(newRentals, 999, 1111, 10);
	ASSERT_SUCCESS(rentalsCustomerPayBill(newRentals, 999));
	ASSERT_TEST(RENTALS_INVALID_CUSTOMER_ID == rentalsCustomerPayBill(
					newRentals, 999));

	rentalsDestroy(newRentals);
	return true;
}

bool test_rentalsPrintAvailableCars() {
	Rentals newRentals = rentalsCreateNew();
	FILE *fakeFile = NULL;
	ASSERT_NULL(rentalsPrintAvailableCars(NULL, fakeFile));
	ASSERT_TEST(RENTALS_NO_CARS == rentalsPrintAvailableCars(newRentals,
			fakeFile));
	rentalsAddNewCar(newRentals, 9090, "SUV", 12, 80);
	rentalsAddNewCustomer(newRentals, 888, "Lior");
	rentalsCustomerRentCar(newRentals, 888, 9090);
	ASSERT_TEST(RENTALS_NO_CARS == rentalsPrintAvailableCars(newRentals,
			fakeFile));

	rentalsDestroy(newRentals);
	return true;
}

bool test_rentalsPrintOpenBills() {
	Rentals newRentals = rentalsCreateNew();
	FILE * fakeFile = NULL;
	ASSERT_NULL(rentalsPrintOpenBills(NULL, fakeFile));
	ASSERT_TEST(RENTALS_NO_OPEN_BILLS == rentalsPrintOpenBills(newRentals,
			fakeFile));
	rentalsAddNewCar(newRentals, 9088, "Sabb", 12, 80);
	rentalsAddNewCustomer(newRentals, 888, "Yarin");
	rentalsCustomerRentCar(newRentals, 888, 9090);
	rentalsCustomerReturnCar(newRentals, 888, 9088, 10);
	rentalsCustomerPayBill(newRentals, 888);
	ASSERT_TEST(RENTALS_NO_OPEN_BILLS == rentalsPrintOpenBills(newRentals,
			fakeFile));

	rentalsDestroy(newRentals);
	return true;
}

bool test_rentalsPrintCustomerBill() {
	Rentals newRentals = rentalsCreateNew();
	FILE * fakeFile = NULL;
	ASSERT_NULL(rentalsPrintCustomerBill(NULL, 12345, fakeFile));
	ASSERT_TEST(RENTALS_INVALID_CUSTOMER_ID == rentalsPrintCustomerBill(
					newRentals, 1234, fakeFile));

	rentalsDestroy(newRentals);
	return true;
}

bool test_rentalsPrintIncomeSummary() {
	Rentals newRentals = rentalsCreateNew();
	FILE * fakeFile = NULL;
	ASSERT_NULL(rentalsPrintIncomeSummary(NULL, fakeFile));
	ASSERT_TEST(RENTALS_NO_SALES == rentalsPrintIncomeSummary(newRentals,
			fakeFile));

	rentalsDestroy(newRentals);
	return true;
}

int main() {
	RUN_TEST(test_rentalsCreateNew);
	RUN_TEST(test_rentalsDestroy);
	RUN_TEST(test_retnalsAddNewCar);
	RUN_TEST(test_rentalsRemoveCar);
	RUN_TEST(test_rentalsPutOnSale);
	RUN_TEST(test_rentalsEndSale);
	RUN_TEST(test_rentalsAddNewCustomer);
	RUN_TEST(test_rentalsCustomerRentCar);
	RUN_TEST(test_rentalsCustomerReturnCar);
	RUN_TEST(test_rentalsCustomerPayBill);
	/**
	 * the tests for the following printing functions is only partial and will
	 * include only the error return values because the actual printing can't be
	 * tested within this test and will be tested via the main program itself.
	 */
	RUN_TEST(test_rentalsPrintAvailableCars);
	RUN_TEST(test_rentalsPrintOpenBills);
	RUN_TEST(test_rentalsPrintCustomerBill);
	RUN_TEST(test_rentalsPrintIncomeSummary);

	return 0;
}

